/*
helferlein.com ( http://www.helferlein.com )
Michael Tobisch

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions 
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Entities.Users;
using DotNetNuke.Services.Search;
using helferlein.DNN.Modules.Form.Data;
using helferlein.IO;
using helferlein.DNN.Modules.BabelFish.Business;
using DotNetNuke.Security;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Localization;
using DotNetNuke.Services.FileSystem;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Security.Roles;

namespace helferlein.DNN.Modules.Form.Business
{
#region Data Methods
   [DataObject]
   public class FormSubmissionController : BaseController, ISearchable, IPortable, IUpgradeable
   {
      private PortalSecurity _portalSecurity = null;
      private BabelFishController _babelFishController = null;
      private LocaleController _localeController = null;

      protected PortalSecurity PortalSecurity
      {
         get
         {
            if (_portalSecurity == null)
               _portalSecurity = new PortalSecurity();
            return _portalSecurity;
         }
      }

      protected BabelFishController BabelFishController
      {
         get
         {
            if (_babelFishController == null)
               _babelFishController = new BabelFishController();
            return _babelFishController;
         }
      }

      protected LocaleController LocaleController
      {
         get
         {
            if (_localeController == null)
               _localeController = new LocaleController();
            return _localeController;
         }
      }

      [DataObjectMethod(DataObjectMethodType.Select, true)]
      public FormSubmissionInfo Get(int formSubmissionID)
      {
         return (FormSubmissionInfo)(CBO.FillObject(DataProvider.Instance().GetFormSubmission(formSubmissionID), typeof(FormSubmissionInfo)));
      }

      [DataObjectMethod(DataObjectMethodType.Select, false)]
      public List<FormSubmissionInfo> GetAll(int moduleID)
      {
         return CBO.FillCollection<FormSubmissionInfo>(DataProvider.Instance().GetFormSubmissions(moduleID));
      }

      [DataObjectMethod(DataObjectMethodType.Select, false)]
      public List<FormSubmissionInfo> Get(int moduleID, DateTime formSubmissionDate)
      {
         return CBO.FillCollection<FormSubmissionInfo>(DataProvider.Instance().GetCurrentFormSubmissions(moduleID, formSubmissionDate));
      }

      [DataObjectMethod(DataObjectMethodType.Select, false)]
      public List<FormSubmissionInfo> GetPublic(int moduleID, DateTime formSubmissionDate)
      {
         return CBO.FillCollection<FormSubmissionInfo>(DataProvider.Instance().GetPublicFormSubmissions(moduleID, formSubmissionDate));
      }

      [DataObjectMethod(DataObjectMethodType.Insert, true)]
      public int Add(int moduleID, DateTime formSubmissionDate, string formSubmission, bool formSubmissionApproved, string formSubmissionIPAddress, string formSubmissionLocale)
      {
         return (int)(DataProvider.Instance().AddFormSubmission(moduleID, formSubmissionDate, formSubmission, formSubmissionApproved, formSubmissionIPAddress, formSubmissionLocale));
      }

      [DataObjectMethod(DataObjectMethodType.Insert, false)]
      public int Add(FormSubmissionInfo formSubmissionInfo)
      {
         return (int)(DataProvider.Instance().AddFormSubmission(formSubmissionInfo.ModuleID, formSubmissionInfo.FormSubmissionDate, formSubmissionInfo.FormSubmission, formSubmissionInfo.FormSubmissionApproved, formSubmissionInfo.FormSubmissionIPAddress, formSubmissionInfo.FormSubmissionLocale));
      }

      [DataObjectMethod(DataObjectMethodType.Update, true)]
      public void Change(int moduleID, int formSubmissionID, DateTime formSubmissionDate, string formSubmission, bool formSubmissionApproved, string formSubmissionIPAddress, string formSubmissionLocale)
      {
         DataProvider.Instance().UpdateFormSubmission(moduleID, formSubmissionID, formSubmissionDate, formSubmission, formSubmissionApproved, formSubmissionIPAddress, formSubmissionLocale);
      }

      [DataObjectMethod(DataObjectMethodType.Update, false)]
      public void Change(FormSubmissionInfo formSubmissionInfo)
      {
         DataProvider.Instance().UpdateFormSubmission(formSubmissionInfo.ModuleID, formSubmissionInfo.FormSubmissionID, formSubmissionInfo.FormSubmissionDate, formSubmissionInfo.FormSubmission, formSubmissionInfo.FormSubmissionApproved, formSubmissionInfo.FormSubmissionIPAddress, formSubmissionInfo.FormSubmissionLocale);
      }

      [DataObjectMethod(DataObjectMethodType.Delete, true)]
      public void Drop(int formSubmissionID)
      {
         DataProvider.Instance().DeleteFormSubmission(formSubmissionID);
      }

      [DataObjectMethod(DataObjectMethodType.Delete, false)]
      public void DropAll(int moduleID)
      {
         DataProvider.Instance().DeleteAllFormSubmissions(moduleID);
      }
#endregion

#region ISearchable Members
      public SearchItemInfoCollection GetSearchItems(ModuleInfo modInfo)
      {
         SearchItemInfoCollection searchItems = new SearchItemInfoCollection();

         object o = modInfo.ModuleSettings["WhereToDisplayToDisplayApprovedSubmissions"];
         ShowAdditionalItems whereToDisplayToDisplayApprovedSubmissions = (o == null ? ShowAdditionalItems.NotAtAll : (ShowAdditionalItems)Convert.ToInt32(o));

         if (whereToDisplayToDisplayApprovedSubmissions != ShowAdditionalItems.NotAtAll)
         {
            DateTime since = new DateTime();

            double keepDays = Convert.ToDouble(modInfo.ModuleSettings["KeepDays"]);

            if (keepDays == 0)
               since = new DateTime(1800, 1, 1);
            else
               since = DateTime.Now.AddDays((-1) * keepDays);
            List<FormSubmissionInfo> publicSubmissions = this.GetPublic(modInfo.ModuleID, since);
            SearchItemInfo searchItem;

            DotNetNuke.Data.DataProvider.Instance().DeleteSearchItem(modInfo.ModuleID);

            foreach (FormSubmissionInfo submission in publicSubmissions)
            {
               searchItem = new SearchItemInfo();
               searchItem.Author = 2;
               StringBuilder sb = new StringBuilder("");

               try
               {
                  List<FormItemInfo> formSubmission = submission.GetSubmissionFromXml();

                  bool includeMailAddressesInSearch = Convert.ToBoolean(modInfo.ModuleSettings["IncludeMailAddressesInSearch"]);

                  foreach (FormItemInfo formItem in formSubmission)
                  {
                     switch (formItem.FormItemType)
                     {
                        case FormItemType.DropDownList:
                        case FormItemType.RadioButtonList:
                        case FormItemType.TextArea:
                        case FormItemType.TextBox:
                        case FormItemType.WebSite:
                           sb.Append(formItem.FormItemSelectedValue.Trim() + " ");
                           break;
                        case FormItemType.EMailAddress:
                           if (includeMailAddressesInSearch)
                              sb.Append(formItem.FormItemSelectedValue.Trim() + " ");
                           break;
                        case FormItemType.MultipleSelect:
                           sb.Append(formItem.FormItemSelectedValue.Trim().Replace(';', ' ') + " ");
                           break;
                        default:
                           break;
                     }
                  }
               }
               catch (Exception ex)
               {
                  Exceptions.LogException(ex);
                  sb.Remove(0, sb.Length);
               }

               searchItem.Content = sb.ToString();
               searchItem.Description = sb.ToString();
               searchItem.ModuleId = modInfo.ModuleID;
               searchItem.PubDate = submission.FormSubmissionDate;
               searchItem.SearchKey = String.Format("FormSubmission-{0}-{1}", modInfo.ModuleID, submission.FormSubmissionID);
               StringBuilder title = new StringBuilder();
               title.Append(TabController.GetTab(modInfo.TabID, modInfo.PortalID, true).TabName);
               title.Append(" &raquo; ");
               title.Append(modInfo.ModuleTitle);
               if (!(String.IsNullOrEmpty(submission.GroupItemValue)))
               {
                  title.Append(" &raquo; ");
                  title.Append(submission.GroupItemValue);
               }
               if (!(String.IsNullOrEmpty(submission.HeadlineValue)))
               {
                  title.Append(" &raquo; ");
                  title.Append(submission.HeadlineValue);
               }
               searchItem.Title = title.ToString();
               searchItems.Add(searchItem);
            }
         }
         return searchItems;
      }
#endregion

#region IPortable Members

      public string ExportModule(int moduleID)
      {
         PortalSettings ps = null;
         HttpContext context = null;
         List<BabelFishInfo> aquarium;

         int senderAddressFormItemID = 0;
         int groupOutputByFormItemID = 0;
         int renderAsHeadlineFormItemID = 0;
         int addToDropDownListFormItemID = 0;

         if (HttpContext.Current != null)
         {
            ps = PortalController.GetCurrentPortalSettings();
            context = HttpContext.Current;

            base.Initialize(ps.PortalId, moduleID);

            StringBuilder xmlExport = new StringBuilder(string.Empty);
            StringBuilder xmlFiles = new StringBuilder(string.Empty);

            List<FormItemInfo> exportForm = new FormItemController().GetAll(moduleID);
            List<FormSubmissionInfo> exportSubmissions = this.GetAll(moduleID);

            if (exportForm.Count > 0)
            {
               xmlExport.Append("<helferleinForm>\r\n");

               // Export Settings
               xmlExport.Append("<helferleinFormSettings>\r\n");
               Hashtable settings = base.ModuleController.GetModuleSettings(moduleID);

               base.ModuleID = moduleID;

               foreach (DictionaryEntry setting in settings)
               {
                  string settingValue = Convert.ToString(setting.Value);
                  string settingKey = Convert.ToString(setting.Key);

                  switch (settingKey)
                  {
                     case "SenderAddress":
                        if (settingValue.StartsWith("[FORMITEM]"))
                           senderAddressFormItemID = Convert.ToInt32(settingValue.Substring(10));
                        else if (settingValue.StartsWith("[USERID]"))
                        {
                           // does not make sense as long as we have no UserController method to find a portal user by email
                           // for cross-portal import/export
                           // so this is a dummy...
                           xmlExport.Append(String.Empty);
                        }
                        else // "[ADMIN]" or "[HOST]"
                        {
                           xmlExport.Append("<");
                           xmlExport.Append(settingKey);
                           xmlExport.Append(">");
                           xmlExport.Append(settingValue);
                           xmlExport.Append("</");
                           xmlExport.Append(settingKey);
                           xmlExport.Append(">\r\n");
                        }
                        break;
                     case "RedirectUrl":
                        if ((settings["RedirectUrlType"] == null) && (settingValue.StartsWith("http")))
                        {
                           // We can export this if we go to a specified Url
                           xmlExport.Append("<");
                           xmlExport.Append(settingKey);
                           xmlExport.Append(">");
                           xmlExport.Append(settingValue);
                           xmlExport.Append("</");
                           xmlExport.Append(settingKey);
                           xmlExport.Append(">\r\n");
                        }
                        else
                        {
                           // a TabID does not make sense for cross-portal import/export
                           // so this is a dummy
                           xmlExport.Append(String.Empty);
                        }
                        break;
                     case "RedirectUrlType":
                        // handled more or less in "RedirectUrl"
                        break;
                     case "Theme":
                        // get the StyleSheet
                        if (!(String.IsNullOrEmpty(settingValue)))
                        {
                           string fileName = String.Format("{0}DesktopModules\\{1}\\Themes\\{2}\\{2}.css", HttpContext.Current.Request.PhysicalApplicationPath, base.Configuration.DesktopModule.FolderName, settingValue);
                           if (File.Exists(fileName))
                           {
                              xmlExport.Append("<Theme>");
                              xmlExport.Append(settingValue);
                              xmlExport.Append("</Theme>\r\n");
                              if ((settingValue != "Default") && (settingValue != "DNN_Feedback") && (settingValue != "Fancy"))
                              {
                                 xmlExport.Append("<ThemeFolder>Module</ThemeFolder>");
                                 xmlExport.Append("<ThemeFile><![CDATA[");
                                 xmlExport.Append(FileTools.File2String(fileName));
                                 xmlExport.Append("]]></ThemeFile>\r\n");
                              }
                           }
                           else
                           {
                              fileName = String.Format("{0}helferlein\\helferlein_Form\\Themes\\{1}\\{1}.css", ps.HomeDirectoryMapPath, settingValue);
                              if (File.Exists(fileName))
                              {
                                 xmlExport.Append("<Theme>");
                                 xmlExport.Append(settingValue);
                                 xmlExport.Append("</Theme>\r\n");
                                 xmlExport.Append("<ThemeFolder>Portal</ThemeFolder>");
                                 xmlExport.Append("<ThemeFile><![CDATA[");
                                 xmlExport.Append(FileTools.File2String(fileName));
                                 xmlExport.Append("]]></ThemeFile>\r\n");
                              }
                           }
                        }
                        break;
                     case "GroupOutputBy":
                        groupOutputByFormItemID = Convert.ToInt32(settingValue.Substring(10));
                        break;
                     case "RenderAsHeadline":
                        renderAsHeadlineFormItemID = Convert.ToInt32(settingValue.Substring(10));
                        break;
                     case "AddToDropDownList":
                        addToDropDownListFormItemID = Convert.ToInt32(settingValue.Substring(10));
                        break;
                     default:
                        xmlExport.Append("<");
                        xmlExport.Append(settingKey);
                        xmlExport.Append("><![CDATA[");
                        xmlExport.Append(settingValue);
                        xmlExport.Append("]]></");
                        xmlExport.Append(settingKey);
                        xmlExport.Append(">\r\n");
                        break;
                  }
               }
               xmlExport.Append("</helferleinFormSettings>\r\n");

               // Export ML Settings
               aquarium = this.BabelFishController.GetStrings(ps.PortalId, String.Format("helferlein.Form.Settings.{0}", moduleID));
               if (aquarium != null)
               {
                  xmlExport.Append("<helferleinFormMLSettings>\r\n");
                  foreach (BabelFishInfo fish in aquarium)
                  {
                     xmlExport.Append("<BabelFish>\r\n");

                     // Locale
                     xmlExport.Append("<Locale>");
                     xmlExport.Append(fish.Locale);
                     xmlExport.Append("</Locale>\r\n");

                     // Key
                     xmlExport.Append("<Key>");
                     xmlExport.Append(fish.StringKey);
                     xmlExport.Append("</Key>\r\n");

                     // Value
                     xmlExport.Append("<Value><![CDATA[");
                     xmlExport.Append(fish.StringText);
                     xmlExport.Append("]]></Value>\r\n");

                     xmlExport.Append("</BabelFish>\r\n");
                  }
                  xmlExport.Append("</helferleinFormMLSettings>\r\n");
               }

               // Export Form Items
               xmlExport.Append("<helferleinFormItems>\r\n");

               foreach (FormItemInfo fii in exportForm)
               {
                  xmlExport.Append("<helferleinFormItem>\r\n");
                  // Type
                  xmlExport.Append("<FormItemType>");
                  xmlExport.Append(Convert.ToInt32(fii.FormItemType));
                  xmlExport.Append("</FormItemType>\r\n");

                  // Repeat Columns
                  if (fii.FormItemRepeatColumns != null)
                  {
                     xmlExport.Append("<FormItemRepeatColumns>");
                     xmlExport.Append(fii.FormItemRepeatColumns);
                     xmlExport.Append("</FormItemRepeatColumns>\r\n");
                  }
                  else
                     xmlExport.Append("<FormItemRepeatColumns />\r\n");

                  // Sort Value
                  xmlExport.Append("<SortValue>");
                  xmlExport.Append(fii.SortValue);
                  xmlExport.Append("</SortValue>\r\n");

                  // Required
                  xmlExport.Append("<FormItemRequired>");
                  xmlExport.Append(fii.FormItemRequired);
                  xmlExport.Append("</FormItemRequired>\r\n");

                  // Width
                  if (fii.Width != null)
                  {
                     xmlExport.Append("<Width>");
                     xmlExport.Append(fii.Width);
                     xmlExport.Append("</Width>\r\n");
                  }
                  else
                     xmlExport.Append("<Width />\r\n");

                  // Height
                  if (fii.Height != null)
                  {
                     xmlExport.Append("<Height>");
                     xmlExport.Append(fii.Height);
                     xmlExport.Append("</Height>\r\n");
                  }
                  else
                     xmlExport.Append("<Height />\r\n");

                  // Link Target
                  if ((fii.FormItemLinkTarget != null) && (fii.FormItemLinkTarget != LinkTarget.None))
                  {
                     xmlExport.Append("<FormItemLinkTarget>");
                     xmlExport.Append(Convert.ToInt32(fii.FormItemLinkTarget));
                     xmlExport.Append("</FormItemLinkTarget>\r\n");
                  }
                  else
                     xmlExport.Append("<FormItemLinkTarget />\r\n");

                  // Validation Expression
                  if (!(String.IsNullOrEmpty(fii.ValidationExpression)))
                  {
                     xmlExport.Append("<ValidationExpression><![CDATA[");
                     xmlExport.Append(fii.ValidationExpression);
                     xmlExport.Append("]]>\r\n");
                  }
                  else
                     xmlExport.Append("<ValidationExpression />\r\n");

                  // FormItemOther
                  if (fii.FormItemOther)
                  {
                     xmlExport.Append("<FormItemOther>");
                     xmlExport.Append(fii.FormItemOther);
                     xmlExport.Append("</FormItemOther>\r\n");
                  }
                  else
                     xmlExport.Append("<FormItemOther />");

                  // Special
                  // Form item is sender address
                  xmlExport.Append("<FormItemIsSenderAddress>");
                  xmlExport.Append(fii.FormItemID == senderAddressFormItemID);
                  xmlExport.Append("</FormItemIsSenderAddress>");
                  // Form item is grouping field
                  xmlExport.Append("<FormItemIsGroupByItem>");
                  xmlExport.Append(fii.FormItemID == groupOutputByFormItemID);
                  xmlExport.Append("</FormItemIsGroupByItem>");
                  // Form item is rendered as headline
                  xmlExport.Append("<FormItemIsRenderedAsHeadline>");
                  xmlExport.Append(fii.FormItemID == renderAsHeadlineFormItemID);
                  xmlExport.Append("</FormItemIsRenderedAsHeadline>");
                  // Form item is added to DropDownList (in Form Submisssion Edit)
                  xmlExport.Append("<FormItemIsRAddedToDropDownList>");
                  xmlExport.Append(fii.FormItemID == addToDropDownListFormItemID);
                  xmlExport.Append("</FormItemIsRAddedToDropDownList>");

                  // Only if we have a portal context... (we should ;-))
                  if (ps != null)
                  {
                     // Export the localizable properties in each language
                     aquarium = this.BabelFishController.GetStrings(ps.PortalId, "helferlein.Form.FormItem." + Convert.ToString(fii.FormItemID), false);

                     xmlExport.Append("<Aquarium>\r\n");
                     foreach (BabelFishInfo fish in aquarium)
                     {
                        if (!(String.IsNullOrEmpty(fish.StringText)))
                        {
                           xmlExport.Append("<BabelFish>\r\n");

                           // Locale
                           xmlExport.Append("<Locale>");
                           xmlExport.Append(fish.Locale);
                           xmlExport.Append("</Locale>\r\n");

                           // Key
                           xmlExport.Append("<Key>");
                           xmlExport.Append(fish.StringKey);
                           xmlExport.Append("</Key>\r\n");

                           // Value
                           xmlExport.Append("<Value><![CDATA[");
                           xmlExport.Append(fish.StringText);
                           xmlExport.Append("]]></Value>\r\n");

                           xmlExport.Append("</BabelFish>\r\n");
                        }
                     }
                     xmlExport.Append("</Aquarium>\r\n");
                  }

                  xmlExport.Append("</helferleinFormItem>\r\n");
               }
               xmlExport.Append("</helferleinFormItems>\r\n");

               // Export Form Submissions
               if (exportSubmissions.Count > 0)
               {
                  xmlExport.Append("<helferleinFormSubmissions>\r\n");
                  foreach (FormSubmissionInfo fsi in exportSubmissions)
                  {
                     xmlExport.Append("<helferleinFormSubmission>\r\n");

                     // Date
                     xmlExport.Append("<FormSubmissionDate>");
                     xmlExport.Append(fsi.FormSubmissionDate.ToBinary());
                     xmlExport.Append("</FormSubmissionDate>\r\n");

                     // Submission
                     xmlExport.Append("<FormSubmission>");
                     xmlExport.Append(fsi.FormSubmission);
                     xmlExport.Append("</FormSubmission>\r\n");

                     // Approved
                     xmlExport.Append("<FormSubmissionApproved>");
                     xmlExport.Append(fsi.FormSubmissionApproved);
                     xmlExport.Append("</FormSubmissionApproved>\r\n");

                     // IP Address
                     if (!(String.IsNullOrEmpty(fsi.FormSubmissionIPAddress)))
                     {
                        xmlExport.Append("<FormSubmissionIPAddress>");
                        xmlExport.Append(fsi.FormSubmissionIPAddress);
                        xmlExport.Append("</FormSubmissionIPAddress>\r\n");
                     }
                     else
                        xmlExport.Append("<FormSubmissionIPAddress />\r\n");

                     if (!(String.IsNullOrEmpty(fsi.FormSubmissionLocale)))
                     {
                        xmlExport.Append("<FormSubmissionLocale>");
                        xmlExport.Append(fsi.FormSubmissionLocale);
                        xmlExport.Append("</FormSubmissionLocale>\r\n");
                     }
                     else
                        xmlExport.Append("<FormSubmissionLocale />\r\n");

                     // Only if we have a Portal context...
                     if (ps != null)
                     {
                        List<FormItemInfo> form = fsi.GetSubmissionFromXml(fsi.FormSubmission);
                        foreach (FormItemInfo formItem in form)
                        {
                           if ((formItem.FormItemType == FormItemType.FileUpload) && (!(String.IsNullOrEmpty(formItem.FormItemSelectedValue))))
                           {
                              if (xmlFiles.Length > 0) xmlFiles.Remove(0, xmlFiles.Length);
                              string fileName = String.Format("{0}{1}helferlein\\helferlein_Form\\{2}\\{3}\\{4}", ps.HomeDirectoryMapPath, (ps.HomeDirectoryMapPath.EndsWith("\\") ? String.Empty : "\\"), Base.UPLOAD_FOLDER, moduleID, formItem.FormItemSelectedValue);
                              if (File.Exists(fileName))
                              {
                                 xmlFiles.Append("<File>\r\n<FileName><![CDATA[");
                                 xmlFiles.Append(formItem.FormItemSelectedValue);
                                 xmlFiles.Append("]]></FileName>\r\n");
                                 xmlFiles.Append("<Content><![CDATA[");
                                 xmlFiles.Append(FileTools.File2String(fileName));
                                 xmlFiles.Append("]]></Content>\r\n");
                                 xmlFiles.Append("</File>\r\n");
                              }
                           }
                        }
                        if (xmlFiles.Length > 0)
                        {
                           xmlExport.Append("<Files>");
                           xmlExport.Append(xmlFiles);
                           xmlExport.Append("</Files>\r\n");
                        }
                     }
                     xmlExport.Append("</helferleinFormSubmission>\r\n");
                  }
                  xmlExport.Append("</helferleinFormSubmissions>\r\n");
               }
               xmlExport.Append("</helferleinForm>\r\n");
            }
            return xmlExport.ToString();
         }
         else
            return string.Empty;
      }

      public void ImportModule(int moduleID, string content, string version, int userID)
      {
         string[] ver = version.Split(new char[] { '.' });
         int major = Convert.ToInt32(ver[0]);
         int minor = Convert.ToInt32(ver[1]);
         int build = Convert.ToInt32(ver[2]);
         FormItemController fic = new FormItemController();

         ModuleController mc = new ModuleController();
         Hashtable settings = new Hashtable();

         PortalSettings ps = PortalController.GetCurrentPortalSettings();
         HttpContext context = HttpContext.Current;

         XmlNode helferleinForm = Globals.GetContent(content, "helferleinForm");

         base.ModuleID = moduleID;

         try
         {
            if ((context != null) && (helferleinForm != null))
            {
               XmlNode helferleinFormSettings = helferleinForm.SelectSingleNode("helferleinFormSettings");
               XmlNode helferleinFormMLSettings = helferleinForm.SelectSingleNode("helferleinFormMLSettings");
               XmlNode helferleinFormItems = helferleinForm.SelectSingleNode("helferleinFormItems");
               XmlNode helferleinFormSubmissions = helferleinForm.SelectSingleNode("helferleinFormSubmissions");

               if (major == 1)
               {
                  // Versions 1.x
                  this.ImportLegacy(moduleID, mc, ps, fic, version, settings, helferleinFormSettings, helferleinFormItems, helferleinFormSubmissions);
               }
               else
               {
                  // Versions 2.x
                  // Restore Settings
                  if (helferleinFormSettings != null)
                  {
                     foreach (XmlNode helferleinFormSetting in helferleinFormSettings)
                        settings.Add(helferleinFormSetting.Name, (String.IsNullOrEmpty(helferleinFormSetting.InnerText) ? String.Empty : helferleinFormSetting.InnerText));

                     foreach (DictionaryEntry setting in settings)
                     {
                        string settingKey = Convert.ToString(setting.Key);
                        string settingValue = Convert.ToString(setting.Value);

                        switch (settingKey)
                        {
                           case "RedirectURL":
                              // Only import this setting when it is a redirection to an Url
                              // TabIDs don't make sense in cross-portal export/import
                              if ((String.IsNullOrEmpty(Convert.ToString(settings["RedirectUrlType"]))) && (settingValue.StartsWith("http")))
                                 mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                              else
                                 mc.DeleteModuleSetting(moduleID, settingKey);
                              break;
                           case "RedirectURLType":
                              // Handled in RedirectUrl
                              break;
                           case "SenderAddress":
                              if ((settingValue == "[HOST]") || (settingValue == "[ADMIN]"))
                                 mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                              else
                                 mc.DeleteModuleSetting(moduleID, settingKey);
                              break;
                           case "Theme":
                              if (String.IsNullOrEmpty(settingValue))
                                 mc.DeleteModuleSetting(moduleID, settingKey);
                              else
                              {
                                 try
                                 {
                                    if (Convert.ToString(settings["ThemeFolder"]) == "Portal")
                                    {
                                       Helpers.CheckFolder(base.PortalID, String.Format("helferlein/helferlein_Form/Themes/{0}", settingValue), true);
                                       FileTools.String2File(Convert.ToString(settings["ThemeFile"]), String.Format("{0}{1}helferlein\\helferlein_Form\\Themes\\{2}\\{2}.css", ps.HomeDirectoryMapPath, (ps.HomeDirectoryMapPath.EndsWith("\\") ? String.Empty : "\\"), settingValue));
                                    }
                                    else
                                    {
                                       if ((settingValue != "Default") && (settingValue != "DNN_Feedback") && (settingValue != "Fancy") && (settingValue != "Disabled"))
                                       {
                                          string folder = String.Format("{0}DesktopModules\\{1}\\Themes\\{2}", HttpContext.Current.Request.PhysicalApplicationPath, base.Configuration.DesktopModule.FolderName, settingValue);
                                          if (!(Directory.Exists(folder)))
                                             FileSystemUtils.AddFolder(ps, String.Format("{0}DesktopModules\\{1}\\Themes", HttpContext.Current.Request.PhysicalApplicationPath, base.Configuration.DesktopModule.FolderName), settingValue, Convert.ToInt32(DotNetNuke.Services.FileSystem.FolderController.StorageLocationTypes.InsecureFileSystem));
                                          FileTools.String2File(Convert.ToString(settings["ThemeFile"]), String.Format("{0}{1}{2}.css", folder, (folder.EndsWith("\\") ? String.Empty : "\\"), settingValue));
                                       }
                                    }
                                    mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                                 }
                                 catch (Exception ex)
                                 {
                                    Exceptions.LogException(ex);
                                 }
                              }
                              break;
                           case "ThemeFolder":
                           case "ThemeFile":
                              // Handled in Theme
                              break;
                           default:
                              if (String.IsNullOrEmpty(settingValue))
                                 mc.DeleteModuleSetting(moduleID, settingKey);
                              else
                                 mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                              break;
                        }
                     }
                  }

                  // Restore ML Settings
                  if (helferleinFormMLSettings != null)
                  {
                     // Get all locales - also disabled ones...
                     Dictionary<string, Locale> localeList = this.LocaleController.GetLocales(Null.NullInteger);
                     foreach (XmlNode babelFish in helferleinFormMLSettings.ChildNodes)
                     {
                        if (localeList.ContainsKey(babelFish["Locale"].InnerText))
                           this.BabelFishController.Add(ps.PortalId, babelFish["Locale"].InnerText, String.Format("helferlein.Form.Settings.{0}", moduleID), babelFish["Key"].InnerText, babelFish["Value"].InnerText);
                     }
                  }

                  // Restore Form Items
                  if (helferleinFormItems != null)
                  {
                     foreach (XmlNode helferleinFormItem in helferleinFormItems)
                     {
                        FormItemInfo fii = new FormItemInfo();
                        fii.ModuleID = moduleID;

                        // Type
                        fii.FormItemType = (FormItemType)Enum.GetValues(typeof(FormItemType)).GetValue(Convert.ToInt32(helferleinFormItem["FormItemType"].InnerText) - 1);

                        // Repeat Columns
                        if ((!(string.IsNullOrEmpty(helferleinFormItem["FormItemRepeatColumns"].InnerText))) && (helferleinFormItem["FormItemRepeatColumns"].InnerText != "0"))
                           fii.FormItemRepeatColumns = Convert.ToInt32(helferleinFormItem["FormItemRepeatColumns"].InnerText);

                        // Sort Value
                        fii.SortValue = Convert.ToInt32(helferleinFormItem["SortValue"].InnerText);

                        // Required
                        fii.FormItemRequired = Convert.ToBoolean(helferleinFormItem["FormItemRequired"].InnerText);

                        // Width
                        if ((!(String.IsNullOrEmpty(helferleinFormItem["Width"].InnerText))) && (helferleinFormItem["Width"].InnerText != "0"))
                           fii.Width = Convert.ToInt32(helferleinFormItem["Width"].InnerText);

                        // Height
                        if ((!(String.IsNullOrEmpty(helferleinFormItem["Height"].InnerText))) && (helferleinFormItem["Height"].InnerText != "0"))
                           fii.Height = Convert.ToInt32(helferleinFormItem["Height"].InnerText);

                        // Link Target
                        if ((helferleinFormItem["FormItemLinkTarget"] != null) && (helferleinFormItem["FormItemLinkTarget"].InnerText != "0"))
                        {
                           fii.FormItemLinkTarget = (LinkTarget)Enum.GetValues(typeof(LinkTarget)).GetValue(Convert.ToInt32(helferleinFormItem["FormItemLinkTarget"].InnerText) - 1);
                        }

                        // Validation Expression
                        if ((helferleinFormItem["ValidationExpression"] != null) && (!(String.IsNullOrEmpty(helferleinFormItem["ValidationExpression"].InnerText))))
                           fii.ValidationExpression = helferleinFormItem["ValidationExpression"].InnerText;

                        // FormItemOther
                        if (helferleinFormItem["FormItemOther"] != null)
                        {
                           bool formItemOther;
                           if (Boolean.TryParse(helferleinFormItem["FormItemOther"].InnerText, out formItemOther))
                              fii.FormItemOther = formItemOther;
                        }

                        // Localizable properties
                        Dictionary<string, string> aquarium = new Dictionary<string, string>();
                        XmlNode helferleinFormItemAquarium = helferleinFormItem.SelectSingleNode("Aquarium");
                        if (helferleinFormItemAquarium != null)
                        {
                           foreach (XmlNode babelFish in helferleinFormItemAquarium.SelectNodes("BabelFish"))
                              aquarium.Add(babelFish["Key"].InnerText + "." + babelFish["Locale"].InnerText, this.PortalSecurity.InputFilter(babelFish["Value"].InnerText, PortalSecurity.FilterFlag.NoMarkup));
                        }
                        int formItemID = fic.Add(fii, aquarium);

                        if (helferleinFormItem["FormItemIsGroupByItem"] != null)
                        {
                           bool formItemIsGroupByItem;
                           if (Boolean.TryParse(helferleinFormItem["FormItemIsGroupByItem"].InnerText, out formItemIsGroupByItem))
                           {
                              if (formItemIsGroupByItem)
                              {
                                 mc.UpdateModuleSetting(moduleID, "GroupOutputBy", String.Format("[FORMITEM]{0}", formItemID));
                              }
                           }
                        }

                        if (helferleinFormItem["FormItemIsRenderedAsHeadline"] != null)
                        {
                           bool formItemIsRenderedAsHeadline;
                           if (Boolean.TryParse(helferleinFormItem["FormItemIsRenderedAsHeadline"].InnerText, out formItemIsRenderedAsHeadline))
                           {
                              if (formItemIsRenderedAsHeadline)
                              {
                                 mc.UpdateModuleSetting(moduleID, "RenderAsHeadline", String.Format("[FORMITEM]{0}", formItemID));
                              }
                           }
                        }

                        if (helferleinFormItem["FormItemIsRAddedToDropDownList"] != null)
                        {
                           bool formItemIsRAddedToDropDownList;
                           if (Boolean.TryParse(helferleinFormItem["FormItemIsRAddedToDropDownList"].InnerText, out formItemIsRAddedToDropDownList))
                           {
                              if (formItemIsRAddedToDropDownList)
                              {
                                 mc.UpdateModuleSetting(moduleID, "AddToDropDownList", String.Format("[FORMITEM]{0}", formItemID));
                              }
                           }
                        }
                     }
                  }
                  // Restore submissions
                  this.ImportSubmissions(moduleID, version, helferleinFormSubmissions, ps);
               }
            }
         }
         catch (Exception ex)
         {
            Exceptions.LogException(ex);
         }
      }

      private void ImportLegacy(int moduleID, ModuleController mc, PortalSettings ps, FormItemController fic, string version, Hashtable settings, XmlNode helferleinFormSettings, XmlNode helferleinFormItems, XmlNode helferleinFormSubmissions)
      {
         Dictionary<string, string> specialItems = new Dictionary<string, string>();

         // Restore Settings
         if (helferleinFormSettings != null)
         {
            foreach (XmlNode helferleinFormSetting in helferleinFormSettings)
               settings.Add(helferleinFormSetting.Name, (String.IsNullOrEmpty(helferleinFormSetting.InnerText) ? String.Empty : helferleinFormSetting.InnerText));

            foreach (DictionaryEntry setting in settings)
            {
               string settingKey = Convert.ToString(setting.Key);
               string settingValue = Convert.ToString(setting.Value);

               switch (settingKey)
               {
                  case "RedirectURL":
                     // Only import this setting when it is a redirection to an Url
                     // TabIDs don't make sense in cross-portal export/import
                     if ((String.IsNullOrEmpty(Convert.ToString(settings["RedirectUrlType"]))) && (settingValue.StartsWith("http")))
                        mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                     else
                        mc.DeleteModuleSetting(moduleID, settingKey);
                     break;
                  case "RedirectURLType":
                     // Handled more or less in RedirectUrl
                     break;
                  case "AddToDropDownList":
                     specialItems.Add("AddToDropDownList", settingValue);
                     break;
                  case "GroupOutputBy":
                     specialItems.Add("GroupOutputBy", settingValue);
                     break;
                  case "RenderAsHeadline":
                     specialItems.Add("RenderAsHeadline", settingValue);
                     break;
                  case "SenderAddress":
                     if ((settingValue == "[HOST]") || (settingValue == "[ADMIN]") || (String.IsNullOrEmpty(settingValue)))
                     {
                        if (String.IsNullOrEmpty(Convert.ToString(setting.Value)))
                           mc.DeleteModuleSetting(moduleID, settingKey);
                        else
                           mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                     }
                     else if (settingValue.StartsWith("[FORMITEM]"))
                     {
                        specialItems.Add("SenderAddress", settingValue);
                     }
                     else
                     {
                        // User IDs don't make sense in cross-portal export/import
                     }
                     break;
                  case "Subject":
                     // This is moved to the ML settings
                     this.BabelFishController.Add(ps.PortalId, ps.DefaultLanguage, String.Format("helferlein.Form.Settings.{0}", moduleID), settingKey, settingValue);
                     break;
                  default:
                     if (String.IsNullOrEmpty(Convert.ToString(setting.Value)))
                        mc.DeleteModuleSetting(moduleID, settingKey);
                     else
                        mc.UpdateModuleSetting(moduleID, settingKey, settingValue);
                     break;
               }
            }
         }

         // Restore Form Items
         if (helferleinFormItems != null)
         {
            foreach (XmlNode helferleinFormItem in helferleinFormItems.SelectNodes("helferleinFormItem"))
            {
               FormItemInfo fii = new FormItemInfo();
               Dictionary<string, string> aquarium = new Dictionary<string, string>();
               fii.ModuleID = moduleID;
               fii.FormItemType = (FormItemType)Enum.GetValues(typeof(FormItemType)).GetValue(Convert.ToInt32(helferleinFormItem["FormItemType"].InnerText) - 1);
               if (!(string.IsNullOrEmpty(helferleinFormItem["FormItemRepeatColumns"].InnerText)))
                  fii.FormItemRepeatColumns = Convert.ToInt32(helferleinFormItem["FormItemRepeatColumns"].InnerText);
               fii.FormItemLabel = helferleinFormItem["FormItemLabel"].InnerText;
               fii.FormItemValue = helferleinFormItem["FormItemValue"].InnerText;
               fii.FormItemSelectedValue = helferleinFormItem["FormItemSelectedValue"].InnerText;
               fii.SortValue = Convert.ToInt32(helferleinFormItem["SortValue"].InnerText);
               fii.FormItemRequired = Convert.ToBoolean(helferleinFormItem["Required"].InnerText);
               if (!(string.IsNullOrEmpty(helferleinFormItem["Width"].InnerText)))
                  fii.Width = Convert.ToInt32(helferleinFormItem["Width"].InnerText);
               if (!(string.IsNullOrEmpty(helferleinFormItem["Height"].InnerText)))
                  fii.Height = Convert.ToInt32(helferleinFormItem["Height"].InnerText);
               // This was moved to BabelFish - as it is localizable now
               aquarium.Add(String.Format("FormItemLabel.{0}", ps.DefaultLanguage), helferleinFormItem["FormItemLabel"].InnerText);
               aquarium.Add(String.Format("FormItemValue.{0}", ps.DefaultLanguage), helferleinFormItem["FormItemValue"].InnerText);
               aquarium.Add(String.Format("FormItemSelectedValue.{0}", ps.DefaultLanguage), helferleinFormItem["FormItemSelectedValue"].InnerText);

               if (helferleinFormItem["FormItemLinkTarget"] != null)
               {
                  if (!(string.IsNullOrEmpty(helferleinFormItem["FormItemLinkTarget"].InnerText)) && (helferleinFormItem["FormItemLinkTarget"].InnerText != "0"))
                     fii.FormItemLinkTarget = (LinkTarget)Enum.GetValues(typeof(LinkTarget)).GetValue(Convert.ToInt32(helferleinFormItem["FormItemLinkTarget"].InnerText) - 1);
               }
               if (helferleinFormItem["FormItemHelpText"] != null)
               {
                  if (!(string.IsNullOrEmpty(helferleinFormItem["FormItemHelpText"].InnerText)))
                     aquarium.Add(String.Format("FormItemHelpText.{0}", ps.DefaultLanguage), helferleinFormItem["FormItemHelpText"].InnerText);
               }
               fic.Add(fii, aquarium);
            }
         }
         // Special Items
         // These were referred to using the Label value in helferlein_Form 1.x
         // After ML support, this had to be changed
         List<FormItemInfo> theForm = fic.GetAll(moduleID);
         string label;
         foreach (FormItemInfo fii in theForm)
         {
            if ((specialItems.TryGetValue("AddToDropDownList", out label)) && (label == fii.FormItemLabel))
               mc.UpdateModuleSetting(moduleID, "AddToDropDownList", String.Format("[FORMITEM]{0}", fii.FormItemID));
            if ((specialItems.TryGetValue("GroupOutputBy", out label)) && (label == fii.FormItemLabel))
               mc.UpdateModuleSetting(moduleID, "GroupOutputBy", String.Format("[FORMITEM]{0}", fii.FormItemID));
            if ((specialItems.TryGetValue("RenderAsHeadline", out label)) && (label == fii.FormItemLabel))
               mc.UpdateModuleSetting(moduleID, "RenderAsHeadline", String.Format("[FORMITEM]{0}", fii.FormItemID));
         }

         // Restore Submissions
         this.ImportSubmissions(moduleID, version, helferleinFormSubmissions, ps);
      }

      private void ImportSubmissions(int moduleID, string version, XmlNode helferleinFormSubmissions, PortalSettings ps)
      {
         string[] ver = version.Split(new char[] { '.' });
         int major = Convert.ToInt32(ver[0]);
         int minor = Convert.ToInt32(ver[1]);
         int build = Convert.ToInt32(ver[2]);

         // Restore submissions
         if (helferleinFormSubmissions != null)
         {
            foreach (XmlNode helferleinFormSubmission in helferleinFormSubmissions.SelectNodes("helferleinFormSubmission"))
            {
               FormSubmissionInfo fsi = new FormSubmissionInfo();
               fsi.ModuleID = moduleID;

               if ((major == 1) || ((major == 2) && (minor < 3)))
                  fsi.FormSubmission = helferleinFormSubmission["formSubmission"].OuterXml.ToString();
               else
                  fsi.FormSubmission = helferleinFormSubmission["FormSubmission"].OuterXml.ToString();

               // Bug in version 01.00.00: Exported and imported SubmissionDate had to be in the same language
               // settings, otherwise wrong dates appeared or an exception occured.
               // If an exception occurs, the date will be stored as the minimum system date value
               // Bugfix: Date exported as binary value (version 01.00.01)
               if (version == "01.00.00")
               {
                  try
                  {
                     fsi.FormSubmissionDate = Convert.ToDateTime(helferleinFormSubmission["FormSubmissionDate"].InnerText);
                  }
                  catch (Exception ex)
                  {
                     Exceptions.LogException(ex);
                     fsi.FormSubmissionDate = DateTime.MinValue;
                  }
               }
               else
                  fsi.FormSubmissionDate = DateTime.FromBinary(Convert.ToInt64(helferleinFormSubmission["FormSubmissionDate"].InnerText));

               fsi.FormSubmissionApproved = Convert.ToBoolean(helferleinFormSubmission["FormSubmissionApproved"].InnerText);
               fsi.FormSubmissionIPAddress = helferleinFormSubmission["FormSubmissionIPAddress"].InnerText;
               if (major > 1)
                  fsi.FormSubmissionLocale = helferleinFormSubmission["FormSubmissionLocale"].InnerText;

               if (ps != null)
               {
                  Helpers.CheckFolder(ps.PortalId, String.Format("helferlein/helferlein_Form/{0}/{1}", Base.UPLOAD_FOLDER, moduleID), true);
                  XmlNode files = helferleinFormSubmission.SelectSingleNode("Files");

                  if (files != null)
                  {
                     string folder = String.Format("{0}{1}helferlein\\helferlein_Form\\{2}\\{3}", ps.HomeDirectoryMapPath, (ps.HomeDirectoryMapPath.EndsWith("\\") ? String.Empty : "\\"), Base.UPLOAD_FOLDER, moduleID);
                     foreach (XmlNode file in files.SelectNodes("File"))
                     {
                        string fileName = String.Empty;
                        string fileContent = String.Empty;

                        if ((major == 1) || ((major == 2) && (minor < 3)))
                        {
                           fileContent = file.InnerText;
                           List<FormItemInfo> theForm = fsi.GetSubmissionFromXml();
                           foreach (FormItemInfo fii in theForm)
                           {
                              if (fii.FormItemType == FormItemType.FileUpload)
                              {
                                 fileName = fii.FormItemSelectedValue;
                                 break;
                              }
                           }
                           if (String.IsNullOrEmpty(fileName))
                              fileName = String.Format("{0}.txt", Guid.NewGuid());
                        }
                        else
                        {
                           fileContent = file["Content"].InnerText;
                           fileName = file["FileName"].InnerText;
                        }
                        FileTools.String2File(fileContent, String.Format("{0}\\{1}", folder, fileName));
                     }
                  }
               }
               this.Add(fsi);
            }
         }
      }
#endregion

#region IUpgradeable Members
      public string UpgradeModule(string version)
      {
         string[] ver = version.Split(new char[] { '.' });
         int major = Convert.ToInt32(ver[0]);
         int minor = Convert.ToInt32(ver[1]);
         int build = Convert.ToInt32(ver[2]);

         if ((major == 2) && (minor == 3) && (build == 0))
         {
            ArrayList portals = PortalController.GetPortals();
            foreach (PortalInfo pi in portals)
            {
               ArrayList helferleinFormModules = ModuleController.GetModulesByDefinition(pi.PortalID, "helferlein Form");
               foreach (ModuleInfo mi in helferleinFormModules)
               {
                  this.MoveFiles2NewDirStructure(pi.PortalID, mi.ModuleID);
               }
            }
         }
         return "Upgrading to version: " + version;
      }

      private void MoveFiles2NewDirStructure(int portalID, int moduleID)
      {
         try
         {
            // Check if target directory exists
            Helpers.CheckFolder(portalID, String.Format("helferlein/helferlein_Form/{0}/{1}", Base.UPLOAD_FOLDER, moduleID), true);

            PortalSettings ps = new PortalSettings(portalID);
            FolderInfo sourceDirectory = FileSystemUtils.GetFolder(portalID, "helferlein_Form_ReceivedFiles");

            if (sourceDirectory != null)
            {
               List<FormSubmissionInfo> submissions = this.GetAll(moduleID);
               foreach (FormSubmissionInfo fsi in submissions)
               {
                  List<FormItemInfo> form = fsi.GetSubmissionFromXml();
                  foreach (FormItemInfo fii in form)
                  {
                     if (fii.FormItemType == FormItemType.FileUpload)
                     {
                        string fileName = fii.FormItemSelectedValue;
                        string sourceFile = String.Format("{0}{1}helferlein_Form_ReceivedFiles\\{2}", ps.HomeDirectoryMapPath, (ps.HomeDirectoryMapPath.EndsWith("\\") ? String.Empty : "\\"), fileName);
                        string targetFile = String.Format("{0}{1}helferlein\\helferlein_Form\\{2}\\{3}\\{4}", ps.HomeDirectoryMapPath, (ps.HomeDirectoryMapPath.EndsWith("\\") ? String.Empty : "\\"), Base.UPLOAD_FOLDER, moduleID, fileName);
                        FileSystemUtils.MoveFile(sourceFile, targetFile, ps);
                     }
                  }
               }
               FileSystemUtils.DeleteFolder(portalID, new DirectoryInfo(sourceDirectory.PhysicalPath), sourceDirectory.FolderName);
            }
         }
         catch (Exception ex)
         {
            Exceptions.LogException(ex);
         }
      }
#endregion
   }
}